package com.lst.tools.redis.service.impl;

import com.lst.tools.basics.function.OneParamFunction;
import com.lst.tools.redis.service.IRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.BinaryClient;
import redis.clients.jedis.Jedis;
import redis.clients.util.Pool;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 类描述：Redis业务层
 *
 * @author: Frank
 * @date: 2019/09/24 13:51
 * @version: V1.0
 */
@Service
public class RedisService implements IRedisService {


    @Autowired(required = false)
    private Pool<Jedis> pool;

    @Override
    public String set(String key, String value) {
        return execute((jedis) -> jedis.set(key, value));
    }

    @Override
    public String setEx(String key, int expireSeconds, String value) {
        return execute((jedis) -> jedis.setex(key, expireSeconds, value));
    }

    @Override
    public long setNx(String key, String value) {
        return execute((jedis) -> jedis.setnx(key, value));
    }

    @Override
    public long setRange(String key, int offset, String value) {
        return execute((jedis) -> jedis.setrange(key, offset, value));
    }

    @Override
    public String get(String key) {
        return execute((jedis) -> jedis.get(key));
    }

    @Override
    public long del(String... keys) {
        if (keys == null || keys.length == 0) {
            return 0L;
        }
        return execute((jedis) -> jedis.del(keys));
    }

    @Override
    public boolean exists(String key) {
        return execute((jedis) -> jedis.exists(key));
    }

    @Override
    public List<String> mGet(String... keys) {
        if (keys == null || keys.length == 0) {
            return Collections.emptyList();
        }
        return execute((jedis) -> jedis.mget(keys));
    }

    @Override
    public String mSet(String... keysValues) {
        if (keysValues == null || keysValues.length == 0) {
            return "OK";
        }
        return execute((jedis) -> jedis.mset(keysValues));
    }

    @Override
    public long mSetNx(String... keysValues) {
        if (keysValues == null || keysValues.length == 0) {
            return 0L;
        }
        return execute((jedis) -> jedis.msetnx(keysValues));
    }

    @Override
    public String getSet(String key, String value) {
        return execute((jedis) -> jedis.getSet(key, value));
    }

    @Override
    public String getRange(String key, int startOffset, int endOffset) {
        return execute((jedis) -> jedis.getrange(key, startOffset, endOffset));
    }

    @Override
    public long incr(String key) {
        return execute((jedis) -> jedis.incr(key));
    }

    @Override
    public long incrBy(String key, long integer) {
        return execute((jedis) -> jedis.incrBy(key, integer));
    }

    @Override
    public long decr(String key) {
        return execute((jedis) -> jedis.decr(key));
    }

    @Override
    public long decrBy(String key, long integer) {
        return execute((jedis) -> jedis.decrBy(key, integer));
    }

    @Override
    public long strLen(String key) {
        return execute((jedis) -> jedis.strlen(key));
    }

    @Override
    public long hSetNx(String key, String field, String value) {
        return execute((jedis) -> jedis.hsetnx(key, field, value));
    }

    @Override
    public long hSet(String key, String field, String value) {
        return execute((jedis) -> jedis.hset(key, field, value));
    }

    @Override
    public String hMSet(String key, Map<String, String> hash) {
        return execute((jedis) -> jedis.hmset(key, hash));
    }

    @Override
    public String hGet(String key, String field) {
        return execute((jedis) -> jedis.hget(key, field));
    }

    @Override
    public long expire(String key, int seconds) {
        return execute((jedis) -> jedis.expire(key, seconds));
    }

    @Override
    public List<String> hMGet(String key, String... fields) {
        if (fields == null || fields.length == 0) {
            return Collections.emptyList();
        }
        return execute((jedis) -> jedis.hmget(key, fields));
    }

    @Override
    public long hIncrBy(String key, String field, long value) {
        return execute((jedis) -> jedis.hincrBy(key, field, value));
    }

    @Override
    public boolean hExists(String key, String field) {
        return execute((jedis) -> jedis.hexists(key, field));
    }

    @Override
    public long hLen(String key) {
        return execute((jedis) -> jedis.hlen(key));
    }

    @Override
    public long hDel(String key, String... fields) {
        if (fields == null || fields.length == 0) {
            return 0L;
        }
        return execute((jedis) -> jedis.hdel(key, fields));
    }

    @Override
    public Set<String> hKeys(String key) {
        return execute((jedis) -> jedis.hkeys(key));
    }

    @Override
    public List<String> hVals(String key) {
        return execute((jedis) -> jedis.hvals(key));
    }

    @Override
    public Map<String, String> hGetAll(String key) {
        return execute((jedis) -> jedis.hgetAll(key));
    }

    @Override
    public long lPush(String key, String... strs) {
        if (strs == null || strs.length == 0) {
            return 0L;
        }
        return execute((jedis) -> jedis.lpush(key, strs));
    }

    @Override
    public long rPush(String key, String... strs) {
        if (strs == null || strs.length == 0) {
            return 0L;
        }
        return execute((jedis) -> jedis.rpush(key, strs));
    }

    @Override
    public long lInsert(String key, BinaryClient.LIST_POSITION where, String pivot, String value) {
        return execute((jedis) -> jedis.linsert(key, where, pivot, value));
    }

    @Override
    public String lSet(String key, long index, String value) {
        return execute((jedis) -> jedis.lset(key, index, value));
    }

    @Override
    public long lRem(String key, long count, String value) {
        return execute((jedis) -> jedis.lrem(key, count, value));
    }

    @Override
    public String lTrim(String key, long start, long end) {
        return execute((jedis) -> jedis.ltrim(key, start, end));
    }

    @Override
    public String lPop(String key) {
        return execute((jedis) -> jedis.lpop(key));
    }

    @Override
    public String rPop(String key) {
        return execute((jedis) -> jedis.rpop(key));
    }

    @Override
    public String rPopLPush(String srckey, String dstkey) {
        return execute((jedis) -> jedis.rpoplpush(srckey, dstkey));
    }

    @Override
    public String lIndex(String key, long index) {
        return execute((jedis) -> jedis.lindex(key, index));
    }

    @Override
    public long lLen(String key) {
        return execute((jedis) -> jedis.llen(key));
    }

    @Override
    public List<String> lRange(String key, long start, long end) {
        return execute((jedis) -> jedis.lrange(key, start, end));
    }

    @Override
    public long sAdd(String key, String... members) {
        if (members == null || members.length == 0) {
            return 0L;
        }
        return execute((jedis) -> jedis.sadd(key, members));
    }

    @Override
    public long sRem(String key, String... members) {
        if (members == null || members.length == 0) {
            return 0L;
        }
        return execute((jedis) -> jedis.srem(key, members));
    }

    @Override
    public String sPop(String key) {
        return execute((jedis) -> jedis.spop(key));
    }

    @Override
    public Set<String> sDiff(String... keys) {
        if (keys == null || keys.length == 0) {
            return Collections.emptySet();
        }
        return execute((jedis) -> jedis.sdiff(keys));
    }

    @Override
    public long sDiffStore(String dstkey, String... keys) {
        if (keys == null || keys.length == 0) {
            return 0L;
        }
        return execute((jedis) -> jedis.sdiffstore(dstkey, keys));
    }

    @Override
    public Set<String> sInter(String... keys) {
        if (keys == null || keys.length == 0) {
            return Collections.emptySet();
        }
        return execute((jedis) -> jedis.sinter(keys));
    }

    @Override
    public long sInterStore(String dstkey, String... keys) {
        if (keys == null || keys.length == 0) {
            return 0L;
        }
        return execute((jedis) -> jedis.sinterstore(dstkey, keys));
    }

    @Override
    public Set<String> sUnion(String... keys) {
        if (keys == null || keys.length == 0) {
            return Collections.emptySet();
        }
        return execute((jedis) -> jedis.sunion(keys));
    }

    @Override
    public long sUnionStore(String dstkey, String... keys) {
        if (keys == null || keys.length == 0) {
            return 0L;
        }
        return execute((jedis) -> jedis.sunionstore(dstkey, keys));
    }

    @Override
    public long sMove(String srckey, String dstkey, String member) {
        return execute((jedis) -> jedis.smove(srckey, dstkey, member));
    }

    @Override
    public long sCard(String key) {
        return execute((jedis) -> jedis.scard(key));
    }

    @Override
    public boolean sIsMember(String key, String member) {
        return execute((jedis) -> jedis.sismember(key, member));
    }

    @Override
    public String sRandMember(String key) {
        return execute((jedis) -> jedis.srandmember(key));
    }

    @Override
    public Set<String> sMembers(String key) {
        return execute((jedis) -> jedis.smembers(key));
    }

    @Override
    public long zAdd(String key, double score, String member) {
        return execute((jedis) -> jedis.zadd(key, score, member));
    }

    @Override
    public long zRem(String key, String... members) {
        if (members == null || members.length == 0) {
            return 0L;
        }
        return execute((jedis) -> jedis.zrem(key, members));
    }

    @Override
    public Double zIncrBy(String key, double score, String member) {
        return execute((jedis) -> jedis.zincrby(key, score, member));
    }

    @Override
    public long zRank(String key, String member) {
        return execute((jedis) -> jedis.zrank(key, member));
    }

    @Override
    public long zRevRank(String key, String member) {
        return execute((jedis) -> jedis.zrevrank(key, member));
    }

    @Override
    public Set<String> zRevRange(String key, long start, long end) {
        return execute((jedis) -> jedis.zrevrange(key, start, end));
    }

    @Override
    public Set<String> zRangeByScore(String key, String max, String min) {
        return execute((jedis) -> jedis.zrangeByScore(key, max, min));
    }

    @Override
    public Set<String> zRangeByScore(String key, double max, double min) {
        return execute((jedis) -> jedis.zrangeByScore(key, max, min));
    }

    @Override
    public long zCount(String key, String min, String max) {
        return execute((jedis) -> jedis.zcount(key, max, min));
    }

    @Override
    public long zCard(String key) {
        return execute((jedis) -> jedis.zcard(key));
    }

    @Override
    public Double zScore(String key, String member) {
        return execute((jedis) -> jedis.zscore(key, member));
    }

    @Override
    public long zRemRangeByRank(String key, long start, long end) {
        return execute((jedis) -> jedis.zremrangeByRank(key, start, end));
    }

    @Override
    public long zRemRangeByScore(String key, double start, double end) {
        return execute((jedis) -> jedis.zremrangeByScore(key, start, end));
    }

    @Override
    public Set<String> keys(String pattern) {
        return execute((jedis) -> jedis.keys(pattern));
    }

    @Override
    public String type(String key) {
        return execute((jedis) -> jedis.type(key));
    }

    public <T> T execute(OneParamFunction<T, Jedis> fun) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            return fun.callback(jedis);
        } finally {
            if (jedis != null) {
                //返回或关闭jedis
                jedis.close();
            }
        }
    }
}
